﻿
using Microsoft.Extensions.DependencyInjection;
using Stee.CAP8.MessageBus.Interface.Interfaces;
using Stee.CAP8.MessageBus.Interface.Models;
using Stee.CAP8.MessageBus.Kafka.Publisher;
using Stee.CAP8.MessageBus.Kafka.Subscriber;
using Stee.CAP8.MessageBus.Sagas.Core.Ioc;
using Stee.CAP8.MessageBus.Sagas.Core.Sagas;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;

namespace Stee.CAP8.MessageBus.Sagas.Core.Extensions
{
    public static class EventBusExtension
    {

     

        public static IServiceCollection AddSagaMiddleware<MessageHandler>(this IServiceCollection services)
            where MessageHandler : class, IHandleMessage<CommandMessage>
        {

            services.AddSingleton<IBus, EventBus>();
            services.AddTransient<IPublisher, PublisherImpl>();
            services.AddTransient<ISubscriber, SubscriberImpl>();
            services.AddSingleton<ISagaStorage, InMemorySagaStorage>();
            services.AddSingleton(typeof(IHandleMessage<CommandMessage>), typeof(MessageHandler));
            var alltypes = Assembly.GetCallingAssembly().GetTypes();

            var typeHandle = typeof(BaseMainSaga<>);
            var implementSagaList = alltypes.Where(x => x.IsSubClassOfRawGeneric(typeHandle)).ToList();


            implementSagaList.ForEach(type =>
            {
                services.AddTransient(type);
                Console.WriteLine("注册成功" + type.FullName);

            });
            var provider = services.BuildServiceProvider();
            SagaContainer.serviceProvider = provider;
            return services;
        }


        public static IServiceCollection UseSaga(this IServiceCollection services, Action<IBus> busAction)
        {
            var provider = services.BuildServiceProvider();
            if (provider == null) throw new ArgumentNullException(nameof(provider));
            if (busAction == null) throw new ArgumentNullException(nameof(busAction));


            var bus = provider.GetService<IBus>();

            busAction(bus);

            return services;
        }



    }
}
